package PrecursorToComposition;

use MassData qw(%BasicInfo);
use POSIX;

sub PrecursorToComposition {
	
	my ($pre_mz, $pre_z, $ppm) = @_;
	my $real_ms = $pre_mz * $pre_z + $BasicInfo{'MonoTable'}->{'H'} * $pre_z;
	#my @candidates;
	my %CompoundTable = %{$BasicInfo{'CompoundTable'}};
	## Generate a candidate dp and see if the nubmer of sulfate and acetate can match successfully.
	my $max_dp = 2 * floor($real_ms / ($CompoundTable{'hexa'} + $CompoundTable{'glcn'}));
	my $min_dp = 2 * ceil($real_ms/(2 * ($CompoundTable{'hexa'} + $CompoundTable{'glcn'})));
	for(my $dp=$min_dp; $dp<=$max_dp; $dp++){
		my $num_hexa = ceil($dp/2);
		my $num_glcn = floor($dp/2);
		## There is no water mass difference due to the double bond of NRE unit.
		my $rest = $real_ms - $num_hexa * $CompoundTable{'hexa'} - $num_glcn * $CompoundTable{'glcn'};
		## Estimation of the number of sulfate groups.
		my $max_sulfate = floor($rest/$CompoundTable{'sg'});
		my $max_ac = $num_glcn;
		for(my $s=$max_sulfate; $s>=0; $s--){
			my $final_ms = $rest - $s * $CompoundTable{'sg'};
			my $est_ac = int($final_ms/$CompoundTable{'ac'} + 0.5);
			last if $est_ac > $max_ac;
			
			my $est_ms = $num_hexa * $CompoundTable{'hexa'} + $num_glcn * $CompoundTable{'glcn'} + $est_ac * $CompoundTable{'ac'} + $s * $CompoundTable{'sg'};
			my $error = abs($real_ms-$est_ms)/$est_ms;
			## Find the right composition.
			## Theoretically there might be some overlapping.
			if($error <= 2*$ppm){
				my @composition = (1, $num_hexa-1, $num_glcn, $s, $est_ac);
				return \@composition;
			} 
		}
		
	}
	return 0;

}

1;
